// Paketinė OS, II variantas
// Edmundas Drūteika
// Vytautas Bačiulis

class Compiler
{
    static boolean doesNotOutOfRange(String value, int range)
    {
        if (Integer.parseInt(value, 16)>=0 && Integer.parseInt(value, 16)<=range)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    static void removeValues(LongObject[] VMMemory)
    {
        for(int i = 0; i < 256; i++)
        {
            VMMemory[i].changeValue(0L);
        }
    }

    public static boolean compile(String file, LongObject[] VMMemory)
    {
        String[] data=ReadWrite.readCode(file);
        if (!data[0].toLowerCase().equals(".data")) return false;
        int i=1;
        while (true)
        {
            if (data[i].toLowerCase().equals(".code")) break;
            String[] tmp=data[i].split(" ");
            if (!(tmp.length == 3) || Long.parseLong(tmp[1], 16)>127 ||
                Long.parseLong(tmp[1],16)< 0 || Long.parseLong(tmp[2], 16)<0
                || Long.parseLong(tmp[2],16)>4294967295L)
            {
                removeValues(VMMemory);
                return false;
            }
            VMMemory[Integer.parseInt(tmp[1],16)+128].changeValue(Long.parseLong(tmp[2],16));
            i++;
        }
        i++;
        int commandNumber=0;
        while (true)
        {
            String[] tmp=data[i].split(" ");
            if (tmp[0].toLowerCase().equals("move") && tmp.length==3)
            {
                if (tmp[1].toLowerCase().equals("ax") &&
                   !tmp[2].toLowerCase().equals("/bx") &&
                   doesNotOutOfRange(tmp[2], 127))
                {
                    VMMemory[commandNumber++].changeValue((1L*256L+Long.parseLong(tmp[2], 16))*256L*256L);
                    i++;
                    continue;
                }
                else if (tmp[1].toLowerCase().equals("bx") &&
                         !tmp[2].toLowerCase().equals("/ax") &&
                         doesNotOutOfRange(tmp[2], 127))
                {
                    VMMemory[commandNumber++].changeValue((2L*256L+Long.parseLong(tmp[2], 16))*256L*256L);
                    i++;
                    continue;
                }
                else if (tmp[2].toLowerCase().equals("ax") &&
                         !tmp[1].toLowerCase().equals("/bx") &&
                          doesNotOutOfRange(tmp[1], 127))
                {
                    VMMemory[commandNumber++].changeValue((3L*256L+Long.parseLong(tmp[1], 16))*256L*256L);
                    i++;
                    continue;
                }
                else if (tmp[2].toLowerCase().equals("bx") &&
                         !tmp[1].toLowerCase().equals("/ax") &&
                         doesNotOutOfRange(tmp[1], 127))
                {
                    VMMemory[commandNumber++].changeValue((4L*256L+Long.parseLong(tmp[1], 16))*256L*256L);
                    i++;
                    continue;
                }
                else if (tmp[1].toLowerCase().equals("ax") &&
                         tmp[2].toLowerCase().equals("/bx"))
                {
                    VMMemory[commandNumber++].changeValue(5L*256L*256L*256L);
                    i++;
                    continue;
                }
                else if (tmp[1].toLowerCase().equals("bx") &&
                         tmp[2].toLowerCase().equals("/ax"))
                {
                    VMMemory[commandNumber++].changeValue(6L*256L*256L*256L);
                    i++;
                    continue;
                }
                else if (tmp[1].toLowerCase().equals("/bx") &&
                         tmp[2].toLowerCase().equals("ax"))
                {
                    VMMemory[commandNumber++].changeValue(7L*256L*256L*256L);
                    i++;
                    continue;
                }
                else if (tmp[1].toLowerCase().equals("/ax") &&
                         tmp[2].toLowerCase().equals("bx"))
                {
                    VMMemory[commandNumber++].changeValue(8L*256L*256L*256L);
                    i++;
                    continue;
                }
                else
                {
                    removeValues(VMMemory);
                    return false;
                }


            }
            else if (tmp[0].toLowerCase().equals("add") &&
                     tmp.length==1)
            {
                VMMemory[commandNumber++].changeValue(9L*256L*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("sub") &&
                     tmp.length==1)
            {
                VMMemory[commandNumber++].changeValue(10L*256L*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("cmp") &&
                     tmp.length==1)
            {
                VMMemory[commandNumber++].changeValue(11L*256L*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("jmp") &&
                     tmp.length==2 && doesNotOutOfRange(tmp[1],127))
            {
                VMMemory[commandNumber++].changeValue((12L*256L+Long.parseLong(tmp[1],16))*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("je") &&
                     tmp.length==2 && doesNotOutOfRange(tmp[1],127))
            {
                VMMemory[commandNumber++].changeValue((13L*256L+Long.parseLong(tmp[1],16))*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("jne") &&
                     tmp.length==2 && doesNotOutOfRange(tmp[1],127))
            {
                VMMemory[commandNumber++].changeValue((14L*256L+Long.parseLong(tmp[1],16))*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("ja") &&
                     tmp.length==2 && doesNotOutOfRange(tmp[1],127))
            {
                VMMemory[commandNumber++].changeValue((15L*256L+Long.parseLong(tmp[1],16))*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("jb") &&
                     tmp.length==2 && doesNotOutOfRange(tmp[1],127))
            {
                VMMemory[commandNumber++].changeValue((16L*256L+Long.parseLong(tmp[1],16))*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("jea") &&
                     tmp.length==2 && doesNotOutOfRange(tmp[1],127))
            {
                VMMemory[commandNumber++].changeValue((17L*256L+Long.parseLong(tmp[1],16))*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("jeb") &&
                     tmp.length==2 && doesNotOutOfRange(tmp[1],127))
            {
                VMMemory[commandNumber++].changeValue((18L*256L+Long.parseLong(tmp[1],16))*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("in") &&
                     tmp.length==2 && doesNotOutOfRange(tmp[1],3))
            {
                VMMemory[commandNumber++].changeValue((19L*256L+Long.parseLong(tmp[1],16))*256L*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("out") &&
                     tmp.length==3 && doesNotOutOfRange(tmp[1],127) &&
                     doesNotOutOfRange(tmp[2],3))
            {
                VMMemory[commandNumber++].changeValue(((20L*256L+Long.parseLong(tmp[1],16))*256L+Long.parseLong(tmp[2], 16))*256L);
                i++;
                continue;
            }
            else if (tmp[0].toLowerCase().equals("end"))
            {
                VMMemory[commandNumber++].changeValue(21L*256L*256L*256L);
                i++;
                break;
            }
            else
            {
                removeValues(VMMemory);
                return false;
            }
        }
        return true;
    }

}
